﻿using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace GrainManage.Encrypt
{
    public class RSAEncrypt
    {
        public static void CreateKeyFile(string path, bool saveAsText)
        {
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
            {
                if (saveAsText)
                {
                    string xmlString = RSA.ToXmlString(true);
                    File.WriteAllText(path, xmlString);
                }
                else
                {
                    byte[] blob = RSA.ExportCspBlob(true);
                    File.WriteAllBytes(path, blob);
                }
            }
        }

        public static string GeneratePrivateKey()
        {
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
            {
                string xml = RSA.ToXmlString(true);
                return xml;
            }
        }

        public static string ExtractPublicKey(string xmlString)
        {
            string publicKey = string.Empty;
            if (!string.IsNullOrEmpty(xmlString))
            {
                using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
                {
                    RSA.FromXmlString(xmlString);
                    publicKey = RSA.ToXmlString(false);
                }
            }
            return publicKey;
        }

        public static string ExtractPublicKey(byte[] keyBlob)
        {
            string publicKey = string.Empty;
            if (keyBlob != null && keyBlob.Length > 0)
            {
                using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
                {
                    RSA.ImportCspBlob(keyBlob);
                    publicKey = RSA.ToXmlString(false);
                }
            }
            return publicKey;
        }

        public static byte[] ConvertToBlob(string xmlString, bool includePrivateKey)
        {
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
            {
                RSA.FromXmlString(xmlString);
                byte[] blob = RSA.ExportCspBlob(includePrivateKey);
                return blob;
            }
        }

        public static string ConvertToXml(byte[] keyBlob, bool includePrivateKey)
        {
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
            {
                RSA.ImportCspBlob(keyBlob);
                string xml = RSA.ToXmlString(includePrivateKey);
                return xml;
            }
        }

        public static string Decrypt(string hexCode, string privateKey)
        {
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
            {
                RSA.FromXmlString(privateKey);
                byte[] encryptedData = FormatConvertor.FromHexString(hexCode);
                byte[] decryptedData = RSA.Decrypt(encryptedData, false);
                string utf8code = Encoding.UTF8.GetString(decryptedData);
                return utf8code;
            }
        }

        public static string Decrypt(string hexCode, byte[] privateKey)
        {
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
            {
                RSA.ImportCspBlob(privateKey);
                byte[] encryptedData = FormatConvertor.FromHexString(hexCode);
                byte[] decryptedData = RSA.Decrypt(encryptedData, false);
                string utf8code = Encoding.UTF8.GetString(decryptedData);
                return utf8code;
            }
        }

        public static string Encrypt(string toEncryptString, string publicKey)
        {
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
            {
                RSA.FromXmlString(publicKey);
                byte[] dataToEncrypt = Encoding.UTF8.GetBytes(toEncryptString);
                byte[] encryptedData = RSA.Encrypt(dataToEncrypt, false);
                string hexString = FormatConvertor.ToHexString(encryptedData);
                return hexString;
            }
        }

        public static string Encrypt(string toEncryptString, byte[] publicKey)
        {
            using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
            {
                RSA.ImportCspBlob(publicKey);
                byte[] dataToEncrypt = Encoding.UTF8.GetBytes(toEncryptString);
                byte[] encryptedData = RSA.Encrypt(dataToEncrypt, false);
                string hexString = FormatConvertor.ToHexString(encryptedData);
                return hexString;
            }
        }

        public static RSAParameters GetRsaParameters(string xmlString, bool includePrivateParameters = false)
        {
            RSAParameters para = new RSAParameters();
            if (!string.IsNullOrEmpty(xmlString))
            {
                using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
                {
                    RSA.FromXmlString(xmlString);
                    para = RSA.ExportParameters(includePrivateParameters);
                }
            }
            return para;
        }

    }
}
